/*
 * Copyright (C) 2012 genzo
 */
package jp.gr.java_conf.genzo.wolrepeater;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;

import net.londatiga.android.ActionItem;
import net.londatiga.android.QuickAction;
import net.londatiga.android.QuickAction.OnActionItemClickListener;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.ToggleButton;

import com.google.ads.AdRequest;
import com.google.ads.AdView;

/**
 * メインアクティビティ.
 */
public class WolRepeaterActivity extends Activity {

    /** インテント KEY 更新時の機材情報. **/
    public static final String ITEM = "item";

    /** インテント KEY 更新時の機材情報. **/
    public static final String EDIT_INDEX = "edit_index";

    /** アクティビティ連携 追加. */
    private static final int ACTIVITY_ID_ADD = 1001;

    /** アクティビティ連携 更新. */
    private static final int ACTIVITY_ID_EDIT = 1002;

    /**
     * モデル取得.
     *
     * @return モデル
     */
    private Model getModel() {
        return WolRepeaterApp.getApp().getModel();
    }

    /*
     * (非 Javadoc)
     *
     * @see android.app.Activity#onCreate(android.os.Bundle)
     */
    @Override
    public final void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_wol);

        // Admob
        AdView adView = findView(R.id.adView);
        AdRequest req = new AdRequest();
        if (BuildConfig.DEBUG) {
            req.addTestDevice(AdRequest.TEST_EMULATOR);
        }
        adView.loadAd(req);

        final QuickAction<Integer> quickAction = new QuickAction<Integer>(this,
                QuickAction.VERTICAL);
        quickAction.addActionItem(newActionItem(R.string.act_item_del,
                android.R.drawable.ic_menu_delete));
        quickAction.addActionItem(newActionItem(R.string.act_item_edit,
                android.R.drawable.ic_menu_edit));
        // quickAction.addActionItem(newActionItem(R.string.act_item_info,
        // android.R.drawable.ic_menu_info_details));
        quickAction
        .setOnActionItemClickListener(new OnActionItemClickListener() {
            @Override
            public void onItemClick(QuickAction<?> source, int pos,
                    int actionId) {
                int index = quickAction.getItem();
                MachineInfo item = getModel().get(index);
                switch (actionId) {
                case R.string.act_item_del:
                    getModel().remove(index);
                    break;
                case R.string.act_item_edit:
                    Intent intent = new Intent(
                            WolRepeaterActivity.this,
                            EditItemActivity.class);
                    intent.putExtra(ITEM, item);
                    intent.putExtra(EDIT_INDEX, index);
                    startActivityForResult(intent, ACTIVITY_ID_EDIT);
                    break;
                default:
                    break;
                }

            }
        });

        final MyArrayAdapter adapter = new MyArrayAdapter(this,
                R.layout.main_list, getModel().get());
        ListView list = findView(R.id.item_list);
        list.setAdapter(adapter);
        list.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                quickAction.show(view);
                quickAction.setItem(position);
            }
        });

        // モデル更新イベント通知リスナー登録
        getModel().addPropertyChangeListener(adapter);
        // ping
        sendPing();
    }

    /**
     * アクションバー情報登録.
     *
     * @param messageId
     *            テキストリソースID
     * @param resId
     *            画像リソースID
     * @return ActionItemのインスタンス
     */
    private ActionItem newActionItem(int messageId, int resId) {
        return new ActionItem(messageId, getString(messageId), getResources()
                .getDrawable(resId));
    }

    /*
     * (非 Javadoc)
     *
     * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
     */
    @SuppressLint("NewApi")
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_wol, menu);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            MenuItem run = menu.findItem(R.id.menu_run);
            run.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
            MenuItem stop = menu.findItem(R.id.menu_stop);
            stop.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
        }

        return true;
    }

    /*
     * (非 Javadoc)
     *
     * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        boolean operation = true;

        switch (item.getItemId()) {
        case R.id.menu_add:
            // 追加
            startActivityForResult(new Intent(this, EditItemActivity.class),
                    ACTIVITY_ID_ADD);
            break;
        case R.id.menu_help:
            // Help
            Uri uri = Uri
            .parse("https://sites.google.com/site/gddandroiddev/home/wolrepeater");
            startActivity(new Intent(Intent.ACTION_VIEW, uri));
            break;
        case R.id.menu_refresh:
            // ping
            sendPing();
            break;
        case R.id.menu_run:
            // 実行
            startService(new Intent(this, WolRepeaterService.class));
            break;
        case R.id.menu_stop:
            // 停止
            stopService(new Intent(this, WolRepeaterService.class));
            break;
        default:
            operation = false;
            break;
        }
        return operation ? operation : super.onOptionsItemSelected(item);

    }

    /*
     * (非 Javadoc)
     *
     * @see android.app.Activity#onActivityResult(int, int,
     * android.content.Intent)
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode != RESULT_OK) {
            return;
        }
        MachineInfo item = (MachineInfo) data.getExtras().getSerializable(ITEM);
        int index = data.getExtras().getInt(EDIT_INDEX);

        switch (requestCode) {
        case ACTIVITY_ID_ADD:
            getModel().add(item);
            break;
        case ACTIVITY_ID_EDIT:
            getModel().update(index, item);
            break;
        default:
            break;
        }
    }

    /**
     * Ping送信.
     * 
     * 通信をメインで実行できないため、スレッドで実行
     */
    private void sendPing() {
        (new Thread() {
            @Override
            public void run() {
                WolRepeaterApp.getApp().sendPing();
            };
        }).start();
    }

    /**
     * Viewの検索.
     * 
     * @param <T>
     *            View型
     * @param id
     *            ID
     * @return View
     */
    @SuppressWarnings("unchecked")
    private <T extends View> T findView(int id) {
        return (T) findViewById(id);
    }

    /**
     * リストモデル.
     */
    static class MyArrayAdapter extends ArrayAdapter<MachineInfo> implements
    PropertyChangeListener {

        /** LayoutInflater。 */
        private final LayoutInflater mInflater = (LayoutInflater) WolRepeaterApp
                .getApp().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        /**
         * コンストラクタ.
         *
         * @param context
         *            コンテキスト
         * @param textViewResourceId
         *            ViewリソースID
         * @param objects
         *            初期値
         */
        public MyArrayAdapter(Context context, int textViewResourceId,
                List<MachineInfo> objects) {
            super(context, textViewResourceId, objects);
        }

        /*
         * (非 Javadoc)
         *
         * @see android.widget.ArrayAdapter#getView(int, android.view.View,
         * android.view.ViewGroup)
         */
        @Override
        public View getView(int position, View view, ViewGroup parent) {

            View convertView = view;

            MachineInfo item = getItem(position);

            if (convertView == null) {
                convertView = mInflater.inflate(R.layout.main_list, null);
            }

            setCheck(convertView, R.id.list_toggle, item.isAlive());
            setText(convertView, R.id.list_ip, item.getIp());
            setText(convertView, R.id.list_mac, item.getMac());

            return convertView;
        }

        /**
         * テキスト設定.
         *
         * @param container
         *            コンテナView
         * @param id
         *            リソースID
         * @param text
         *            テキスト
         */
        private void setText(View container, int id, CharSequence text) {
            TextView view = (TextView) container.findViewById(id);
            view.setText(text);
        }

        /**
         * トグルボタン設定.
         *
         * @param container
         *            コンテナView
         * @param id
         *            リソースID
         * @param alive
         *            true:アクティブ false:非アクティブ
         */
        private void setCheck(View container, int id, boolean alive) {
            ToggleButton view = (ToggleButton) container.findViewById(id);
            view.setChecked(alive);

        }

        /**
         * Viewのリフレッシュ.
         */
        public void refresh() {
            clear();
            for (MachineInfo m : WolRepeaterApp.getApp().getModel()) {
                add(m);
            }

            notifyDataSetChanged();
            notifyDataSetInvalidated();
        }

        /*
         * (非 Javadoc)
         *
         * @see java.beans.PropertyChangeListener#propertyChange(java.beans.
         * PropertyChangeEvent)
         */
        @Override
        public void propertyChange(PropertyChangeEvent event) {
            L.d("propertyChange");
            refresh();
        }
    }
}
